package com.gaoding.shared.dict.provider;

import com.gaoding.commons.exception.NotFoundException;
import com.gaoding.commons.exception.ServiceException;
import com.gaoding.commons.exception.ValidateException;
import com.gaoding.grpc.common.protobuf.Common;
import com.gaoding.orm.jpa.search.BaseSearchable;
import com.gaoding.orm.jpa.search.SearchOperator;
import com.gaoding.shared.dict.common.constant.DictMessageConstant;
import com.gaoding.shared.dict.entity.DictServiceLanguage;
import com.gaoding.shared.dict.enums.DictServiceErrorCode;
import com.gaoding.shared.dict.repository.DictServiceLanguageRepository;
import com.gaoding.shared.dict.rpc.service.*;
import com.gaoding.shared.dict.service.DictServiceLanguageService;
import com.google.protobuf.BoolValue;
import com.google.protobuf.Int64Value;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 服务语言配置 grpc实现
 *
 * @author mobai
 * @since 2021/1/28 15:58
 */
@GrpcService
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DictServiceLanguageServiceGrpcImpl extends GdGrpcDictServiceLanguageService {

    /**
     * 服务语言配置 服务组件
     */
    private final DictServiceLanguageService dictServiceLanguageService;

    /**
     * 分页查询
     *
     * @param request 查询参数
     * @return com.gaoding.shared.dict.rpc.service.DictServiceLanguageReply
     * @since 2021/2/1 9:39 上午
     */

    @Override
    public DictServiceLanguageReply list(QueryDictServiceLanguageRequest request) {
        DictServiceLanguageReply reply = DictServiceLanguageReply.newBuilder().addAllData(Collections.emptyList()).build();
        BaseSearchable searchable = BaseSearchable.newSearchable();
        if (StringUtils.isNotBlank(request.getServiceCode())) {
            searchable.addSearchFilter("serviceCode", SearchOperator.eq, request.getServiceCode());
        }
        Common.Page queryPage = request.getPage();
        searchable.setPage(queryPage.getPageNum(), queryPage.getPageSize());
        Page<DictServiceLanguage> serviceLanguagePage = dictServiceLanguageService.findAll(searchable);
        if (!CollectionUtils.isEmpty(serviceLanguagePage.getContent())) {
            List<DictServiceLanguageInfo> serviceLanguageInfos = serviceLanguagePage.getContent().stream().map(data -> DictServiceLanguageInfo.newBuilder().setLanguageCode(data.getLanguageCode()).setServiceCode(data.getServiceCode())
                    .setId(data.getId()).setSort(data.getSort()).setVersion(data.getVersion()).build()).collect(Collectors.toList());
            reply = DictServiceLanguageReply.newBuilder().addAllData(serviceLanguageInfos).build();
        }
        return reply;
    }


    /**
     * 新增单条记录
     *
     * @param request 新增参数
     * @return com.google.protobuf.BoolValue
     * @since 2021/2/1 9:40 上午
     */

    @Override
    public Int64Value create(CreateDictServiceLanguageRequest request) {
        if (StringUtils.isBlank(request.getLanguageCode()) || StringUtils.isBlank(request.getServiceCode())) {
            throw new ValidateException("服务编码和语言编码不得为空");
        }
        //这里需要判断一下是否存在同一个服务和同一个语言配置
        DictServiceLanguageRepository repository = (DictServiceLanguageRepository) dictServiceLanguageService.getRepository();
        List<DictServiceLanguage> serviceLanguages = repository.findByServiceCodeAndLanguageCode(request.getServiceCode(), request.getLanguageCode());
        if (CollectionUtils.isNotEmpty(serviceLanguages)) {
            throw new ServiceException(DictServiceErrorCode.SERVICE_LANGUAGE_CONFIG_EXIST);
        }
        DictServiceLanguage saveEntity = DictServiceLanguage.builder().serviceCode(request.getServiceCode()).status(DictMessageConstant.DEFAULT_STATUS).languageCode(request.getLanguageCode()).sort(request.getSort()).version(0L).build();
        try {

            return Int64Value.of(dictServiceLanguageService.save(saveEntity).getId());
        } catch (Exception e) {
            log.error("新增服务语言配置记录出错，原因:{}", e.getMessage());
            throw e;
        }
    }

    /**
     * 更新单条记录
     *
     * @param request 更新参数
     * @return com.google.protobuf.BoolValue
     * @since 2021/2/1 9:40 上午
     */

    @Override
    public BoolValue update(UpdateDictServiceLanguageRequest request) {
        DictServiceLanguage serviceLanguage = findExistOne(request.getId());
        //这里需要判断一下是否存在同一个服务和同一个语言配置
        DictServiceLanguageRepository repository = (DictServiceLanguageRepository) dictServiceLanguageService.getRepository();
        List<DictServiceLanguage> serviceLanguages = repository.findByServiceCodeAndLanguageCode(request.getServiceCode(), request.getLanguageCode()).stream().filter(data -> !serviceLanguage.getId().equals(data.getId())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(serviceLanguages)) {
            throw new ServiceException(DictServiceErrorCode.SERVICE_LANGUAGE_CONFIG_EXIST);
        }
        serviceLanguage.setServiceCode(request.getServiceCode());
        serviceLanguage.setLanguageCode(request.getLanguageCode());
        try {
            dictServiceLanguageService.save(serviceLanguage);
            return BoolValue.of(true);
        } catch (Exception e) {
            log.error("更新服务语言配置出错,原因:{}", e.getMessage());
            throw e;
        }
    }


    /**
     * 根据id删除（逻辑删除）
     *
     * @param request id
     * @return com.google.protobuf.BoolValue
     * @since 2021/2/1 9:40 上午
     */

    @Override
    public BoolValue delete(Int64Value request) {
        try {
            dictServiceLanguageService.delete(request.getValue());
            return BoolValue.of(true);
        } catch (EmptyResultDataAccessException ignored) {
            log.error("id为{}的服务语言配置记录已不存在", request.getValue());
            throw new NotFoundException(String.format("id为%s的服务语言配置记录已不存在", request.getValue()));
        }
    }

    /**
     * 更新排序值
     *
     * @param request 更新参数
     * @return com.google.protobuf.BoolValue
     * @since 2021/2/1 9:41 上午
     */

    @Override
    public BoolValue updateSort(UpdateDictServiceLanguageRequest request) {
        DictServiceLanguage exist = findExistOne(request.getId());
        exist.setSort(request.getSort());
        try {
            dictServiceLanguageService.save(exist);
            return BoolValue.of(true);
        } catch (Exception e) {
            log.error("更新服务语言配置排序值出错,原因:{}", e.getMessage());
            throw e;
        }
    }


    /**
     * 查询单条记录，不存在则抛异常
     *
     * @param id 主键
     * @return com.gaoding.shared.dict.entity.DictServiceLanguage
     * @since 2021/2/1 9:41 上午
     */

    private DictServiceLanguage findExistOne(long id) {
        return Optional.<DictServiceLanguage>ofNullable(dictServiceLanguageService.findOne(id)).orElseThrow(() -> new ServiceException(DictServiceErrorCode.SERVICE_LANGUAGE_CONFIG_NOT_EXIST));
    }
}
